package com.smap.layer;

import com.google.gwt.canvas.client.Canvas;
import com.google.gwt.canvas.dom.client.Context2d;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.ImageElement;
import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.Style.Position;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.dom.client.Style.Visibility;
import com.smap.common.ResourceLoader;
import com.smap.core.XY;
import com.smap.core.Layer;
import com.smap.core.Map;
import com.smap.event.MapEvent;

public abstract class CanvasLayer implements Layer {

	protected Map map;
	protected Canvas mainCanvas;
	protected XY offset = new XY(0, 0);
	protected int buffer = 400;
	protected int width;
	protected int height;

	public CanvasLayer() {
		mainCanvas = Canvas.createIfSupported();
	}

	public void install(Map map) {
		map.getRoot().add(mainCanvas);
		this.map = map;
	}

	public void clearScreen() {
		mainCanvas.getContext2d().clearRect(0, 0, width, height);
	}

	public void resize(int width, int height) {
		this.width = width + buffer;
		this.height = height + buffer;
		mainCanvas.setWidth(this.width + "px");
		mainCanvas.setCoordinateSpaceWidth(this.width);
		mainCanvas.setHeight(this.height + "px");
		mainCanvas.setCoordinateSpaceHeight(this.height);
		Style style = mainCanvas.getElement().getStyle();
		style.setLeft(-(this.width / 2), Unit.PX);
		style.setTop(-(this.height / 2), Unit.PX);
		style.setPosition(Position.ABSOLUTE);
		offset.x = this.width / 2;
		offset.y = this.height / 2;
		// this.draw();
	}

	void cancelPictures() {
		ResourceLoader.get().clear();
	}

	void drawPicture(String url, int posX, int posY) {
		String info = posX + "," + posY;
		ResourceLoader r = ResourceLoader.get();
		r.loadImg(url, new ResourceLoader.Callback() {
			public void onLoad(Object obj, String info, int inQueue, int running) {
				try {
					ImageElement ele = ImageElement.as((Element) obj);
					String[] p = info.split(",");
					int x = Integer.parseInt(p[0]);
					int y = Integer.parseInt(p[1]);
					Context2d ctx = mainCanvas.getContext2d();
					ctx.drawImage(ele, x, y);
					MapEvent event = new MapEvent(MapEvent.EVT_TILE_FETCHED,
							null);
					event.x = inQueue;
					event.y = running;
					CanvasLayer.this.map.fireEvent(event);
				} catch (Exception e) {

				}
			}
		}, info);
	}

	public Canvas getCanvas() {
		return mainCanvas;
	}

	public Context2d getCtx() {
		return mainCanvas.getContext2d();
	}

	public XY getCanvasOffset() {
		return new XY(-width / 2, -height / 2);
	}

	public XY getDrawingOffset() {
		return new XY(width / 2, height / 2);
	}

	public void setType(Integer index) {
	}

	public void setVisibility(boolean visible) {
		Style st = this.getCanvas().getElement().getStyle();
		if (visible) {
			st.setVisibility(Visibility.VISIBLE);
		} else {
			st.setVisibility(Visibility.HIDDEN);
		}
	}

	@Override
	public void getInfo(int x, int y, InfoHandler handler) {
		handler.execute(null);
	}
}
